fix: term 테이블의 is_current 필드에 UK 설정#650
fix: term 테이블의 is_current 필드에 UK 설정#650whqtker wants to merge 4 commits intosolid-connection:developfrom
Conversation
Walkthrough
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/example/solidconnection/term/domain/Term.java (1)
18-18:⚠️ Potential issue | 🟠 Major@AllArgsConstructor를 제거하여 null 변환 로직 우회 방지
현재 코드에서
@AllArgsConstructor가Term(Long id, String name, Boolean isCurrent)3개 인자 생성자를 자동 생성하고 있습니다. 이는 37-40번 줄의 커스텀 생성자에서 구현한false → null변환 로직을 완전히 우회할 수 있습니다.
발견된 문제
@AllArgsConstructor의3인자 생성자로new Term(1L, "name", false)를 호출하면isCurrent에false가 그대로 저장됨- 34번 줄의 unique 제약에 의해
false값이 하나만 허용되어 의도하지 않은 제약 위반 발생 가능현재 상태
- 코드베이스에서는 2인자 생성자(
new Term(name, isCurrent))만 사용 중- 3인자 생성자 직접 호출은 없음
권장 조치
@AllArgsConstructor제거 (34번 줄 삭제)- 2인자 커스텀 생성자와 setter 메서드만으로 충분
🔧 제안: `@AllArgsConstructor` 제거
`@Getter` `@NoArgsConstructor`(access = AccessLevel.PROTECTED) `@Entity` -@AllArgsConstructor `@Table`(uniqueConstraints = { `@UniqueConstraint`( name = "uk_term_name", columnNames = {"name"} ) }) public class Term {
🤖 Fix all issues with AI agents
In `@src/main/java/com/example/solidconnection/term/domain/Term.java`:
- Around line 42-48: The setAsCurrent()/setAsNotCurrent() pair is fine but must
be used atomically to avoid UNIQUE constraint violations: implement a
transactional service method (e.g., in TermService) that locates the existing
current Term (using the repository method that queries isCurrent), calls
existingTerm.setAsNotCurrent(), then targetTerm.setAsCurrent(), and saves both
within the same `@Transactional` boundary; ensure you use the repository query
(e.g., findByIsCurrentTrue or equivalent) and persist the changes in the same
transaction so the UNIQUE constraint on isCurrent is never violated.
In
`@src/main/resources/db/migration/V45__add_unique_constraint_to_term_is_current.sql`:
- Around line 1-9: 현재 마이그레이션은 term 테이블의 is_current 컬럼에 유니크
제약(uk_term_is_current)을 바로 추가하는데, 사전 검증 없이 동일한 is_current = TRUE 레코드가 2개 이상이면 제약
추가 시 실패합니다; 따라서 V45 마이그레이션에 제약 추가 전에 term 테이블의 is_current가 TRUE인 레코드가 여러 개인지
검사하고(또는 SELECT로 확인한 뒤) 하나만 유지하고 나머지는 NULL로 보정하는 방어 로직을 추가하여 ADD CONSTRAINT
uk_term_is_current 실행 전 데이터 정합성을 보장하세요(대상 식별에 사용할 고유키/updated_at/우선순위 기준을 명시해
하나만 남기도록 업데이트).
src/main/java/com/example/solidconnection/term/domain/Term.java
Outdated
Show resolved
Hide resolved
src/main/resources/db/migration/V46__add_unique_constraint_to_term_is_current.sql
Show resolved
Hide resolved
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/example/solidconnection/term/domain/Term.java (1)
18-18:⚠️ Potential issue | 🟠 Major
@AllArgsConstructor가isCurrent변환 로직을 우회할 수 있습니다.
@AllArgsConstructor는Term(Long id, String name, Boolean isCurrent)생성자를 자동 생성합니다.- 이 생성자는 Line 39의
isCurrent ? true : null변환 로직을 거치지 않습니다.- 따라서
new Term(1L, "2025-1", false)를 호출하면false가 그대로 DB에 저장되어,null기반 UNIQUE 제약 설계 의도가 무너질 수 있습니다.
@AllArgsConstructor를 제거하거나, 테스트 전용이라면 접근 수준을 제한하는 것을 권장합니다.♻️ 수정 제안
-@AllArgsConstructor만약 테스트 등에서 all-args 생성자가 필요하다면,
AccessLevel.PRIVATE으로 제한하세요:-@AllArgsConstructor +@AllArgsConstructor(access = AccessLevel.PRIVATE)
관련 이슈
작업 내용
기존에는
true,false로 현재 학기를 구분했는데, 'true가 단 하나여야 한다'는 조건을 만족하지 않습니다.true만 단 하나가 존재하기 위해서 함수형 인덱스를 설정하는 것은 복잡하고, flyway-jpa 간 매핑도 잘 되지 않기 때문에 필드에 UK만 설정하고, 기존에false였던 값을null로 바꾸도록 수정했습니다.추가로 미사용 도메인 메서드를 제거했습니다. 어드민에서 현재 학기 변경할 때 사용될 수 있지만, 해당 기능 구현할 때 작성하겠습니다.
특이 사항
리뷰 요구사항 (선택)